// Copyright(c) Sonosemi Medical Ltd. Embedded Software Team.
// Author: Zhang Yisong(zhangyisong@sonosemi.com)
#pragma once
#include "active/active_event.hpp"
#include <stdx/ct_conversions.hpp>
#include <stdx/ct_string.hpp>
#include <string_view>
namespace active {

#define ERR_LISTENER_DEFINE(__sm__)                                             \
  template <> inline auto active::error_config<> = boost::sml::sm<__sm__>{};
template <stdx::ct_string name, typename... TArgs>
struct ErrorType : public internal::EventLiteral<name, TArgs...> {};
template <stdx::ct_string name, typename... TArgs> constexpr auto Error() {
  using namespace stdx;
  using namespace stdx::ct_string_literals;
  return boost::sml::unexpected_event<ErrorType<name, TArgs...>>;
}

template <typename TChar, TChar... chars> consteval auto operator""_err() {
  constexpr auto name = stdx::ct_string<sizeof...(chars) + 1U>{{chars..., 0}};
  return boost::sml::unexpected_event<ErrorType<name>>;
};

template <typename T> struct is_error_type : std::false_type {};
template <stdx::ct_string name, typename... TArgs>
struct is_error_type<ErrorType<name, TArgs...>> : std::true_type {};

#define ATV_ERR(name, ...)                                                     \
  auto name = atv::Error<#name __VA_OPT__(, ) __VA_ARGS__>()

} // namespace active